iT邦幫忙

2022 iThome 鐵人賽

DAY 2
0
Web 3

Smart-Contract Language: Move系列 第 2

Day 2 Concept and Coding Conventions

  • 分享至 

  • xImage
  •  

Concept

Move 的兩個核心元素 script , module

Script:

function 執行進入點,主要目的是調用已發布的 module 的 function,這些 function 執行全局存儲模式的更新。

schema

script {
    // 使用聲明來 import (後面會介紹)
    <use>*
        
    // 任何常量
    <constants>*

    // main function
    // 任何數量參數,不能有返回值
    fun <identifier><[type parameters: constraint]*>([identifier: type]*)                     <function_body>
}

example

script {
    // 導入 Debug Module
    use Std::Debug;

    const ONE: u64 = 1;

    fun main(x: u64) {
        let sum = x + ONE;
        Debug::print(&sum)
    }
}

Module:

定義 struct type 以及對這些 type 進行操作的 function 的位置。struct type 定義了 Move 的全局存儲模式 (之後會提到),模塊函數定義了更新存儲的規則。模塊本身也存儲在全局存儲中。

一個 Move source file 可能包含多個 module and script。

注意: Module 中不能使用 let

schema

module <address>::<identifier> {
    (<use> | <friend> | <type> | <function> | <constant>)*
}

example

module 0x42::Test 指定名為 Test 的 Module 將在全局存儲中的帳戶地址(0x42) 下發布。

module 0x42::Test {
    struct Example has copy, drop { i: u64 }

    use Std::Debug; // 使用來自其他 Module 的導入類型
    friend 0x42::AnotherTest; // 指定受信任的 Module 列表

    const ONE: u64 = 1; // 指定常量,可以在 Module 內使用的私有常量

    public fun print(x: u64) {
            ...
    }
}

Conventions - Naming

  • Module names - camel case 範例: FixedPoint, Vector
  • Type names - camel case 範例: Coin, RoleId
  • Function names - lower snake case 範例: destroy_empty
  • Constant names - upper snake case 範例: REQUIRES_CAPABILITY
  • Generic types - 使用描述性的命名。並盡量讓 Modul 裡的 Main Type 與名字一樣,範例: Option::Option, FixedPoint32::FixedPoint32
  • Module file names: 與 Module 名字一樣,範例 Option.move
  • Script file names: lower snake case 並與 Script 裡的 main function 名字一樣
  • Mixed file names: 如果文件包含多個 Module 和 Script ,則應為 lower snake case ,且名稱和內部任何特定 Module / Script 都不匹配

Conventions - Import

  • 所有 Module use 語句都應該在 Module 頂部
  • function 應該從聲明他們的 Module 裡個別導入使用,而不是在頂層導入
  • 類型應該在頂層導入,如果有名稱衝突,可以使用 as 重新命名
// Module

module 0x1::Foo {
    struct Foo { }
    const CONST_FOO: u64 = 0;
    public fun do_foo(): Foo { Foo{} }
    ...
}

// 導入並使用
module 0x1::Bar {
    use 0x1::Foo::{Self, Foo}; // use 宣告在 module 頂部

    public fun do_bar(x: u64): Foo {
        if (x == 10) {
            Foo::do_foo() // function 個別導入,不要在最上面就導入
        } else {
            abort 0
        }
    }
    ...
}

// 名字衝突
module OtherFoo {
    struct Foo {}
    ...
}

module 0x1::Importer {
    use 0x1::OtherFoo::Foo as OtherFoo; // 使用 as
    use 0x1::Foo::Foo;
....
}

Conventions - 註釋

每個 Module Struct, Public function 都應該註釋。

  • doc comments ///
  • single-line comments //
  • block comments /* */

筆者認為,編碼約定主要是清楚得讓自己和其他人可以更好的閱讀程式碼,無論是本章介紹的 Move 團隊或其他格式指南和約定,都沒有限定。

本章介紹了 Module 兩大核心元素和命名規則,有些內容在之後幾天會介紹到,歷時再回頭看本篇或許會更理解,讓我們 Move to Day3。


上一篇
Day 1 前言和整裝待發
下一篇
Day 3 Primitive Types
系列文
Smart-Contract Language: Move30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言